#' @title 获取TCGA表达谱、免疫浸润、药敏预测信息
#'
library(R6)
get_tcga <- R6::R6Class("get_tcga",
    private = list(
        database = "/Pub/Users/wangyk/GEO_Data_ZhangGX/"
    ),
    public = list(
        cancer = NULL,
        type = NULL,
        dir_ = NULL,
        initialize = \(cancer = "BLCA", type = "exprs", ...){
            self$type <- type
            self$cancer <- cancer

            self$type <- match.arg(arg = self$type, choices = c("exprs", "immune", "drug"), T)

            self$dir_ <- switch(self$type,
                exprs = str_glue("{private$database}/TCGA_V36/GDCdata/TCGA-{self$cancer}/clean"),
                immune = str_glue("{private$database}/TCGA_immune_res/TCGA-{self$cancer}/"),
                drug = str_glue("{private$database}/TCGA_drug_res_CTRP2/TCGA-{self$cancer}/calcPhenotype_Output/")
            )
        },
        get_data = \(type_of_data){
            if (missing(type_of_data)) {
                file_dr <- list.files(self$dir_, full.names = T)[1]
                cli::cli_alert_warning("缺少信息，默读取路径中第一个文件。{.path {file_dr[1]}}")
            } else {
                if (self$type == "drug") {
                    file_dr <- list.files(str_glue("{private$database}/TCGA_drug_res_{type_of_data}/TCGA-{self$cancer}/calcPhenotype_Output"),
                        full.names = T, ignore.case = T
                    )[1]
                } else {
                    file_dr <- list.files(self$dir_, full.names = T, pattern = type_of_data, ignore.case = T)[1]
                }
            }
            # print(file_dr)

            read_ <- function(file_dr, ...) {
                if (str_detect(file_dr, "RData")) {
                    e1 <- environment()
                    d <- load(file_dr, envir = e1)
                    d <- get0(d, envir = e1)
                } else {
                    d <- data.table::fread(file_dr)
                }

                return(d)
            }
            d <- read_(file_dr)
            return(d)
        },
        print = \(){
            cli::cli_alert("target directory: {.path {self$dir_}}")
        },
        help = \(){
            lid <- cli::cli_ul()
            cli::cli_li("初始化函数{.var new()}涉及两个参数，一个为癌症类型，第二个是数据类型，包含exprs、immune、durg，对应表达谱信息、免疫浸润信息、药敏反应信息。")
            cli::cli_li("{.var get_data()}涉及一个参数，exprs对应count、tpm、fpkm；immune随意；drug涉及三个数据库对应的分析结果CTRP2、GDSC1、GDSC2。")
            cli::cli_end(lid)
        }
    )
)

if (F) {
    a <- get_tcga$new("LUAD", "drug")
    a
    a$help()
    aa <- a$get_data("CTRP2")
    aa
}


#' @title 模拟python logging 写成的一个R6对象的log处理器
#'
library(R6)
logging <- R6Class("logging",
    public = list(
        name = NULL,
        log_file_path = NULL,
        set_level = NULL,
        set_time_format = NULL,
        set_msg_format = NULL,
        msgs = list(),
        initialize = \(name = "my_log", log_file_path = NULL, set_level = "INFO",
            set_time_format = "%Y-%m-%d %H:%M:%S", set_msg_format = "{level} {name} [{time}]: {msg}"){
            library(stringr)
            self$name <- name
            self$log_file_path <- log_file_path
            if (!is.null(log_file_path)) self$log_file_path <- normalizePath(log_file_path)
            self$set_level <- set_level
            self$set_time_format <- set_time_format
            self$set_msg_format <- set_msg_format
        },
        info = \(msg = NULL) {
            msg_ <- private$msg2chr(msg)
            cli::cli_alert_info(msg_)
            self$msgs <- private$collect_msgs(msg_)
            private$save_log()
        },
        warning = \(msg = NULL) {
            msg_ <- private$msg2chr(msg)
            cli::cli_alert_warning(msg_)
            self$msgs <- private$collect_msgs(msg_)
            private$save_log()
        },
        error = \(msg = NULL) {
            msg_ <- private$msg2chr(msg)
            cli::cli_alert_danger(msg_)
            self$msgs <- private$collect_msgs(msg_)
            private$save_log()
        },
        help = \(){
            message("
        Create a new log object using the logging$new() function, with optional parameters:
         - `name` :indicates the log name in log. The default value is 'my_log'
         - `log_file_path`: specifies the log file output path. The default value is `NULL`. No file output is performed
         - `set_level`: indicates the log level. The default value is 'INFO'
         - `set_time_format`:indicates the time format. The default value is '%Y-%m-%d %H:%M:%S'.
         - `set_msg_format`: log format, defaults to '{level} {name} [{time}]: {msg}'

        Usage:
        logger = logging$new(name = 'test',log_file_path = './log_test.log')
        logger$info('test info')
        # ℹ INFO-test [2024-07-19 13:51:58]: test info
        logger$warning('test warning')
        # ! INFO test [2024-07-19 13:51:58]: test warning
        logger$error('test error')
        # ✖ INFO test [2024-07-19 13:51:58]: test error

        # file log_test.log:
        # INFO test [2024-07-19 13:51:58]: test info
        # INFO test [2024-07-19 13:51:58]: test warning
        # INFO test [2024-07-19 13:51:58]: test error

        Other:
        logger$msgs : print all logs
        ")
        }
    ), private = list(
        msg2chr = \(msg_in_msg2chr = NULL){
            formatted_time <- format(Sys.time(), self$set_time_format)

            level <- self$set_level
            name <- self$name
            time <- formatted_time
            msg <- msg_in_msg2chr

            msg_chr <- str_glue(self$set_msg_format)
            return(msg_chr)
        },
        collect_msgs = \(...){
            self$msgs <- c(self$msgs, list(...))
        },
        save_log = \(){
            if (!is.null(self$log_file_path)) {
                if (!file.exists(self$log_file_path)) {
                    dir.create(dirname(self$log_file_path), recursive = T, showWarnings = F)
                }
                msg_last <- self$msgs[[length(self$msgs)]]
                readr::write_lines(x = msg_last, file = self$log_file_path, append = TRUE)
            }
        }
    )
)

# 牛肉 羊肉 焖面 一碗香 调黄瓜 豆豉鲮鱼炒油麦 五花肉炒豆芽 
